iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
佛心分享-IT 人自學之術

LLM入門學習系列 第 25

Day 25:整合檢索與生成模型 (RAG 基礎版)

  • 分享至 

  • xImage
  •  

一、學習目標與 RAG 核心概念

本日是 FAQ Chatbot 專案的關鍵階段,目標是將 Day 24 建立的 FAISS 向量資料庫LLM 生成模型結合,實現完整的 RAG 工作流程。

任務目標 核心技術
RAG 流程整合 理解並實作 Retriever + Generator 的串接。
知識檢索 透過 FAISS 檢索最相關的知識片段(Context)。
生成回答 Context 餵入 LLM,生成有依據的自然語言回答。

二、環境與實作:RAG 整合範例

(1) 環境需求

確保已安裝所有 RAG 核心套件:

pip install faiss-cpu sentence-transformers transformers torch

(2) 完整 RAG 實作程式碼

# === Step 1. 載入工具 ===
from sentence_transformers import SentenceTransformer
from transformers import pipeline
import faiss
import numpy as np
import pandas as pd # 確保載入 pandas,以便後續進階應用

# === Step 1. 載入工具 (保持不變) ===
# === Step 1. 載入工具 (保持不變) ===
from sentence_transformers import SentenceTransformer
from transformers import pipeline
import faiss
import numpy as np
import pandas as pd # 確保已載入 pandas

# ---Step 2: 載入並處理 CSV 知識庫 ---
try:
    # 讀取 Day 23 產出的 CSV 檔案
    data_df = pd.read_csv("google_faq.csv", encoding="utf-8-sig") 
    
    # 從 DataFrame 中提取問題和答案列表
    knowledge_base_questions = data_df['question'].tolist()
    knowledge_base_answers = data_df['answer'].tolist()
    
    print(f" 已成功載入 {len(knowledge_base_questions)} 筆問答資料。")
    print(f" 知識庫問題範例: {knowledge_base_questions[0]}")
    
except FileNotFoundError:
    print(" 錯誤:找不到 'google_faq.csv' 檔案!請檢查檔案路徑。")
    # 如果找不到檔案,可以選擇使用 Day 25 的假設資料繼續測試
    knowledge_base_questions = ["預設問題 1", "預設問題 2"]
    knowledge_base_answers = ["預設答案 1", "預設答案 2"]


# --- Step 3: 向量化並建立 FAISS 索引 ---
embedder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")

# 注意:我們只需將「問題」向量化,因為檢索是基於「問題的語義相似度」
embeddings = embedder.encode(
    knowledge_base_questions, 
    convert_to_numpy=True
).astype('float32') 

dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings)

print(" 向量資料庫建立完成!索引大小:", index.ntotal)

https://ithelp.ithome.com.tw/upload/images/20251009/20169488PwJQNsJdxB.png

 ===Step 4. 檢索函數 (Retriever) ===
def retrieve(query, top_k=2):
    query_vec = embedder.encode([query], convert_to_numpy=True).astype('float32')
    distances, indices = index.search(query_vec, top_k)
    
    # 這裡,我們將檢索到的問題和答案配對起來作為 Context
    retrieved_context = []
    for i in indices[0]:
        # 將檢索到的問題和對應的標準答案串接起來,作為 LLM 的 Context
        doc = f"問題: {knowledge_base_questions[i]}. 答案: {knowledge_base_answers[i]}"
        retrieved_context.append(doc)
        
    return retrieved_context # 返回一個包含 Top-K 文本片段的列表
# === 測試:使用 CSV 資料集中的問題 ===
user_query = "如何建立 Google 帳號" # 語義相似,但非完全匹配的查詢

# 確保生成器已載入
# generator = pipeline("text-generation", model="distilgpt2") 

print("\n 問題:", user_query)
print(" RAG 回答:\n", rag_answer(user_query))

https://ithelp.ithome.com.tw/upload/images/20251009/201694880JP4yycRZU.png

可以詢問不同問題

https://ithelp.ithome.com.tw/upload/images/20251009/20169488N1WMyJQJV8.png

三、專案障礙與排除:模型生成問題 (Hallucination)

在 RAG 整合測試中,雖然檢索器(Retriever)成功找到了相關知識,但生成器(Generator)輸出了不連貫或重複的內容。這是實務應用中常見的挑戰。

(1) 觀察到的錯誤現象

當輸入查詢 如何建立 Google 帳號 時,模型輸出了包含重複指令的混亂文本:

問題: 如何建立 Google 帳號
 RAG 回答:
 根據以下內容回答問題:問題: 如何建立 Google 帳號?. 答案: 前往 https://accounts.google.com/signup,填寫基本資料即可免費建立 Google 帳號。 問題: 如何設定 Google 雙重驗證?. 答案: 前往帳戶安全設定頁面,開啟「兩步驟驗證」並設定手機或安全金鑰。
問題:如何建立 Google 帳號
回答:如何建立 Google 答案: 答案: 前往帳戶安全設定手機或安全金鑰。 問題:如何建立 Google 答案:

(2) 根本原因分析

這個問題主要出在 LLM 的生成階段,而非檢索階段。根本原因是:

  1. 模型指令遵循能力不足 (DistilGPT2 的限制)
    • distilgpt2 僅有 1.24 億參數,缺乏複雜的指令遵循和推理能力
    • 面對複雜的 RAG Prompt 格式(Context + 詢問 + "回答:"),它難以理解「只根據 Context 回答」的指令,反而傾向於模仿 Prompt 的模式(如重複 問題:)或輸出不連貫的 Token。
  2. Prompt 格式與 Context 複雜度
    • 輸入 Context 包含了多組完整的「問題 + 答案」配對,對於小型模型而言,增加了資訊複雜度,容易混淆其生成起點。

(3) 解決方案與優化建議

要解決這個生成混亂(廣義上的幻覺)問題,必須提升生成器的指令遵循能力簡化輸入

策略 建議做法 效果
升級生成模型 替換為 Llama 3 8B、Mistral 7B 或中文模型(如 Qwen/Llama 系列),必要時使用 API (GPT-3.5/Gemini)。 最有效的解決方案,顯著提升指令遵循能力和回答品質。
優化 Context 輸入 在檢索時,只將 answer 欄位的內容作為 Context 傳給 LLM,避免傳遞重複的 question 資訊。 簡化輸入,減少小模型混淆的可能性。
調整生成參數 設置 do_sample=False(貪婪搜索)並降低 temperature(例如 0.1-0.2)。 讓模型輸出更確定、更保守的結果,減少隨機和混亂的 Token 生成。

結論: 雖然 RAG 系統功能正確,但需要一個指令遵循能力更強大的 LLM 來處理複雜的 RAG Prompt,才能將檢索到的知識有效地轉化為高品質的答案。

四、運作解析:RAG 模組與功能

組件 核心功能 實作方式/套件 備註
Retriever 檢索最相關的知識片段 (Context) SentenceTransformer + FAISS 關鍵在於語義相似度搜索
Generator 根據 Context 產生自然語言回答 Hugging Face pipeline (distilGPT2) Prompt Augmentation 是核心

Prompt Augmentation 是 RAG 的精華:將檢索到的 Context 與使用者 Query 結合,明確指令 LLM 進行有依據的回答,從而避免幻覺。


上一篇
Day 24:建立知識向量資料庫 (Knowledge Vector Database)
系列文
LLM入門學習25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言